#coding=utf-8
from __future__ import division
import numpy as np
import math
import cv2
import platform
import profile
import math
import httplib
import urllib
import re
import time
import hashlib
import json
import os
import pickle
import multiprocessing as mp
import threading
import Queue
import apscheduler
import dataDeal
#import flaskVideo
import random
import sys
import parameter
import systemInfo
#import subprocess
import commands

#stdout_backup = sys.stdout
#log_file = open('main.log','w')
#sys.stdout = log_file


########################################################################################################################
class proportional:
    '''
    @正比例函数类，用于平面坐标判断点和直线的关系
    '''
    x1 = 0
    y1 = 0
    x2 = 0
    y2 = 0
    k = 0
    b = 0
    def __init__(self,a,b,c,d):
        self.x1 = a
        self.y1 = b
        self.x2 = c
        self.y2 = d
        if (self.y1 - self.y2) == 0:
            self.k = 0
            self.b = self.y1
        self.k = (self.y1-self.y2)/(self.x1-self.x2)
        self.b = (self.y1 -self.k*self.x1)*-1
        #print "%f"%self.k,self.b

#定义区域计数线
devconfig = parameter.deviceConfig()
devconfig.loadDevArg()
parameter.setDeviceConfigParam(devconfig.area_y1,devconfig.area_y2,devconfig.area_x1,devconfig.area_x2,devconfig.highlevel)

print parameter.area_x1,parameter.area_x2,parameter.area_y1,parameter.area_y2,parameter.videoHigh,parameter.videoWidth
linea1 = proportional(int(parameter.area_x1*parameter.videoWidth), int(parameter.area_y1*parameter.videoHigh), int(parameter.area_x2*parameter.videoWidth), int(parameter.area_y1*parameter.videoHigh+1))
linea2 = proportional(int(parameter.area_x1*parameter.videoWidth), int(parameter.area_y2*parameter.videoHigh), int(parameter.area_x2*parameter.videoWidth), int(parameter.area_y2*parameter.videoHigh+1))

def checkLinea1(x,y):
    '''
    @第一条计数线与点的位置关系判断
    :param x: x坐标
    :param y: y坐标
    :return: <0 点在线上面  >0 点在线下面 ==0 点在线下面
    '''
    '''if linea1.k < 0 or linea1.b > 0:
        return x - (y-linea1.b)/linea1.k
    else:
    '''
    #linea1 = proportional(int(parameter.area_x1*parameter.videoWidth), int(parameter.area_y1*parameter.videoHigh), int(parameter.area_x2*parameter.videoWidth), int(parameter.area_y1*parameter.videoHigh+1))
    return y - x * linea1.k + linea1.b

def checkLinea2(x,y):
    '''
    @第二条计数线与点的位置关系判断
    :param x:x坐标
    :param y: y坐标
    :return: <0 点在线上面  >0 点在线下面 ==0 点在线中
    '''
    '''if linea2.k < 0 or linea2.b > 0:
        return x - (y-linea2.b)/linea2.k
    else:
    '''
    #linea2 = proportional(int(parameter.area_x1*parameter.videoWidth), int(parameter.area_y2*parameter.videoHigh), int(parameter.area_x2*parameter.videoWidth), int(parameter.area_y2*parameter.videoHigh+1))
    return y - x * linea2.k + linea2.b
########################################################################################################################

########################################################################################################################
#Windows 与 Linux平台相关处理
platformValue = None
WindowsSystem = False
platformValue = platform.system()
if platformValue == "Windows":
    WindowsSystem = True
print platform

########################################################################################################################
def showWinImage(name,image):
    '''
    @在窗口显示一张图片
    :param name: 窗口名称
    :param image: 窗口显示图像
    :return:
    '''
    if platformValue == "Windows":
        cv2.imshow(name, image)

########################################################################################################################
'''
@与帧分辨率、检测尺寸有关的数据定义
'''
NoneCheckSize = 2
pedWidth = 48
pedHigth = 50

class pedestrian():
    '''
    @这是一个行人类，主要功能是描述视频中的行人，行人由中心坐标、矩形坐标、上一帧位置、当前状态等信息。
    @这个类提供 更新行人信息、行人丢失处理、行人显示处理、删除行人等方法
    '''
    actionIn = 1#进入动作
    actionOut = 2#出去动作
    actionNone = 0#初始状态不确定

    statusLost = 1#跟踪丢失状态
    statusIn = 2#跟踪正常状态
    statusInvalid = 3#跟踪失效，行人消失

    def __init__(self,pos,id,frame = None):
        self.id = int(id)
        self.action = self.actionNone #动作信息
        self.pos = pos#中心点位置
        self.oldPos = pos
        self.startPos = pos#起始位置
        self.status = self.statusIn#状态信息
        self.lostWeight = 0#丢失权重
        self.directionWeight = 0#方向权重
        self.cntFlag = False
        self.route = set()
        self.updateFlag = False#更新数据的标志
        self.middleLost = False
        self.colorR = random.randint(0,255)
        self.colorB = random.randint(0,255)
        self.colorG = random.randint(0,255)

    def cntFlagSet(self,arg = True):
        self.cntFlag = arg

    def cntFlagGet(self):
        return self.cntFlag

    def startPosGet(self):
        tmp = 0
        pos = self.startPos
        for i in self.route:
            (posx, posy, x, y, w, h) = i
            (oldx, oldy, ox, oy, ow, oh) = self.pos
            dist = cv2.sqrt((posx - oldx) * (posx - oldx) + (posy - oldy) * (posy - oldy))
            if int(dist[0]) > tmp:
                tmp = int(dist[0])
                pos = i
        return pos

    def getUpdateFlagStatus(self):
        return self.updateFlag

    def getDistInfo(self,tmpQ):
        if (self.status == self.statusIn):
            (posx, posy, x, y, w, h) = tmpQ
            (oldx, oldy, ox, oy, ow, oh) = self.pos
            dist = cv2.sqrt((posx - oldx) * (posx - oldx) + (posy - oldy) * (posy - oldy))
            return int(dist[0])
        else:
            return parameter.moveMinLen

    def updateInfoTrack(self,dist,info):
         if self.status == self.statusIn: #已经被跟踪的人
            self.status = self.statusLost #假设这次找不到就丢失了
            self.lostWeight += 1
            self.updateFlag = True
            if dist != parameter.moveMinLen:
                (oldx, oldy, ox, oy, ow, oh) = info
                self.route.add(self.pos)
                self.oldPos = self.pos

                #(oldx, oldy, ox, oy, ow, oh) = self.route[0]
                self.route.add(self.pos)
                #self.directionWeight = oy - self.route[]
                self.pos = info
                self.status = self.statusIn
                self.lostWeight = 0
            else:#如果这个人不见了
                self.status = self.statusLost
                print  'ped tracking lost'



    def updateInfoTrackLost(self):
        if self.updateFlag == False:
            self.status = self.statusLost

    def updateInfoFlagClear(self):
        self.updateFlag = False

    def updateInfo(self,NewQueue,frame = None):
        if self.status == self.statusIn: #已经被跟踪的人
            self.status = self.statusLost #假设这次找不到就丢失了
            self.lostWeight += 1

            minDistance = parameter.moveMinLen    #每一帧最小移动的距离
            minInfo = set()
            cntMatch = 0
            histMach = 0
            #print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!',self.id
            for info in NewQueue: #当前帧的轮廓列队
                (posx, posy, x, y, w, h) = info
                (oldx, oldy, ox, oy, ow, oh) = self.pos

                dist = cv2.sqrt((posx - oldx) * (posx - oldx) + (posy - oldy) * (posy - oldy))
                if(int(dist[0]) < parameter.moveMinLen):#找到范围里最符合要求的
                    if int(dist[0]) < minDistance:#and tmp >= histMach:#找到更小的移动距离，在连个目标相向运动
                        minDistance = int(dist[0])
                        minInfo = info

            if minDistance != parameter.moveMinLen:#如果发现这个人的新位置
                (oldx, oldy, ox, oy, ow, oh) = minInfo
                self.route.add(self.pos)
                self.oldPos = self.pos
                self.pos = minInfo
                self.status = self.statusIn
                self.lostWeight = 0
                NewQueue.remove(minInfo)#删除这个轮廓
            else: #如果这个人不见了
                self.status = self.statusLost
                print "ped tack lost"

    def getPedOldInfo(self):
        return self.oldPos

    def getPedNewInfo(self):
        return self.pos

    #丢失的轮廓处理
    def lostPoress(self,NewQueue):
        if self.status == self.statusLost:
            (posx, posy, x, y, w, h) = self.pos#检测到的位置
            #if posx < NoneCheckSize or posx > inputImgWidth-NoneCheckSize or (posy-h/2) < NoneCheckSize or (posy+h/2) > inputImgHigth-NoneCheckSize:#如果移动到了监控范围之外
            if (posy-h/2) < NoneCheckSize or (posy+h/2) > parameter.videoHigh-NoneCheckSize:#如果移动到了监控范围之外
                #print 'exit check aera'
                self.status = self.statusInvalid
                return
            minDistance = (parameter.moveMinLen*2)#这个值只允许在合理范围内丢失否则会严重影响计数
            minInfo = set()
            for info in NewQueue:
                posx, posy, x, y, w, h = info
                oldx, oldy, ox, oy, ow, oh = self.pos
                dist = cv2.sqrt((posx - oldx) * (posx - oldx) + (posy - oldy) * (posy - oldy))
                if (int(dist[0]) < (parameter.moveMinLen*2)):
                    if minDistance > int(dist[0]):
                        minDistance = int(dist[0])
                        minInfo = info

            if minDistance != (parameter.moveMinLen*2):#找到这个人
                self.oldPos = self.pos
                self.pos = minInfo
                self.status = self.statusIn
                self.lostWeight = 0
                NewQueue.remove(minInfo)

        if self.status == self.statusLost:
            self.lostWeight += 1
            if self.lostWeight > 5:
                self.status = self.statusInvalid

    def show(self,frame):
        '''if self.kalmanCnt > 10:
            tmp = (self.currentpos[0], self.currentpos[1])
            cv2.circle(frame, tmp, 1, (255, 0, 0), 6)
            cv2.putText(frame, 'Ped' + str(self.id), tmp, cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 255, 255), 1,
                        cv2.LINE_AA)'''
        if self.status == self.statusIn:
            for i in self.route:
                (oldx, oldy, ox, oy, oh, ow) = i
                tmp = (oldx, oldy)
                cv2.circle(frame, tmp, 1, (self.colorB,self.colorG,self.colorR), 4)
            (oldx, oldy, ox, oy, oh, ow) = self.pos
            tmp = (oldx,oldy)
            cv2.circle(frame,tmp,1,(0,255,255),3)
            cv2.putText(frame, str(self.id), tmp, cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1, cv2.LINE_AA)
        elif self.status == self.statusLost:
            (oldx, oldy, ox, oy, oh, ow) = self.pos
            tmp = (oldx,oldy)
            cv2.circle(frame,tmp,3,(255,0,255),6)
    def checkPedExit(self):
        if self.statusInvalid == self.status:
            return True
        else:
            return False



########################################################################################################################
'''
    下面函数部分将会根据全志H3的多核CPU做代码优化，CPU分配任务如下
内核    CPU1                CPU2            CUP3            CUP4
任务    视频采集滤波        背景分割        识别处理        数据处理
输出    Frame               fgmask          人数            http报文
'''
kernel_3x3 = np.array(
    [
        [-1, -1, -1],
        [-1, 8,  -1],
        [-1, -1, -1]
    ]
)

def frameWhiteBalance(frame):
    RGB = cv2.split(frame)
    B = cv2.mean(RGB[0])[0]
    G = cv2.mean(RGB[1])[0]
    R = cv2.mean(RGB[2])[0]

    KB = (R+G+B)/(3*B)
    KG = (R+G+B)/(3*G)
    KR = (R+G+B)/(3*R)

    RGB[0] += KB
    RGB[1] += KG
    RGB[2] += KR

    frame = cv2.merge(RGB)
    return frame

def getCapDistinctFrame(cap):
    '''
    @从摄像头获取一帧图像
    :param cap: 摄像头
    :return: 图像
    '''
    ret, frame = cap.read()

    #如果是Windows一般都做了旋转则不进行旋转处理
    '''
    if WindowsSystem == False:
        frame = cv2.transpose(frame)
        frame = cv2.flip(frame,0)
    '''
    frame = cv2.resize(frame, (parameter.videoWidth, parameter.videoHigh), interpolation=cv2.INTER_AREA)  # 转换时间长
    frame1 = frame.copy()
    #frame = cv2.GaussianBlur(frame,(3,3),0)
    #frame = cv2.blur(frame, (7, 7))
    #frame = cv2.medianBlur(frame,7)
    #frame = cv2.bilateralFilter(frame,7,75,100)
    #frame1 = frame.copy()
    #frame = cv2.blur(frame, (3, 3))
    return frame,frame1

def getFgmaskFrame(fgbg,frame):
    '''
    @获取前景帧图像
    :param fgbg: 分割模型
    :param frame: 图像
    :return: 前景
    '''
    fgmask = fgbg.apply(frame)
    return fgmask



########################################################################################################################
def processCpu1(arg):
    '''
    @CPU1核处理任务
    :param arg: 邮箱
    :return:
    '''
    #time.sleep(1)
    if platform.system() == "Windows":
        cap = cv2.VideoCapture("D:/video/0209.avi")
        #cap = cv2.VideoCapture("http://192.168.1.214:8080/?action=stream?dummy=param.mjpg")
    else:
        cap = cv2.VideoCapture(0)
        #cap = cv2.VideoCapture('./19.avi')
        if cap.isOpened() == False:
            print "cap open is fail"
            cap = cv2.VideoCapture()
            if cap.isOpened() == False:
                print "all cap open is fail"
                exit(-1)
                
        print "open cap ok"
        #cap.set(3, 180)
        #cap.set(4, 240)
        #cap.set(6,"YUYV")
        print  'cur cap hight:',cap.get(4)
        print "cur cap width:",cap.get(3)
        print "cur cap F/S:",cap.get(5)
    #testfbl = 0
    cnt = 0.001
    #cv2.setUseOptimized(True)
    while True:
            frame,frame1 = getCapDistinctFrame(cap)
            arg.put([frame,frame1])
    cap.release()

def processCpu2(arg1,arg2,highmail):
    '''
    @CPU2处理任务
    :param arg1: 输入帧邮箱
    :param arg2: 输出帧邮箱
    :return:
    '''
    time.sleep(1)
    upperBody = cv2.CascadeClassifier("casca/1100.xml")#加载分类器

    cnt = 0
    while True:
        #print  'high',highmail.highlevel
        frame,frame1 = arg1.get()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        gray = cv2.blur(gray, (5, 5))
        #frame = cv2.medianBlur(frame,5)
        peds = set()
        if highmail.highlevel == 1:
            peds = upperBody.detectMultiScale(gray, 1.05 ,3, minSize=(40, 40), maxSize=(80, 80),flags = cv2.CASCADE_SCALE_IMAGE)
        elif highmail.highlevel == 2:
            peds = upperBody.detectMultiScale(gray, 1.05 ,3, minSize=(30, 30), maxSize=(70, 70),flags = cv2.CASCADE_SCALE_IMAGE)
        elif highmail.highlevel == 3:
            peds = upperBody.detectMultiScale(gray, 1.05 ,3, minSize=(25, 25), maxSize=(60, 60),flags = cv2.CASCADE_SCALE_IMAGE)
        elif highmail.highlevel == 4:
            peds = upperBody.detectMultiScale(gray, 1.05 ,3, minSize=(20, 20), maxSize=(50, 50),flags = cv2.CASCADE_SCALE_IMAGE)
        elif highmail.highlevel == 5:
            peds = upperBody.detectMultiScale(gray, 1.05 ,3, minSize=(18, 18), maxSize=(40, 40),flags = cv2.CASCADE_SCALE_IMAGE)

        arg2.put([peds, frame1])
        if WindowsSystem == True:
            time.sleep(0.05)

def processCpu3(arg1,arg2,arg3,dev):
    '''
    @CPU3处理任务
    :param arg1:  输入邮箱
    :param arg2:  输出邮箱
    :param arg3:  输出录像邮箱
    :return:
    '''
    #time.sleep(0.03)
    id = 0  # 目标的ID
    pedQueue = set()
    pointFromAbove = set()  # 上部分的点集合
    pointFromBelow = set()  # 下部分的点集合
    #pointInMiddle = set()  # 中间的点集合
    tempFrame = set()    # 临时帧
    frameBat = set()
    recordFlag = False
    firstFrameFlag = True
    frameSped = 0
    speedtmp = 0
    speedcnt = 0
    preciseInNum = 0#精确计数 进
    preciseOutNum = 0#精确计数 出

    areaMin =  pedWidth*pedHigth
    areaMax = areaMin*4
    systemInfo.get_ip()
    ip = systemInfo.get_ip2("wlan1")
    print ip
    while True:
        recordFlag = False
        p_start = time.time()
        date = time.localtime(p_start)
        if int(date.tm_hour) == 0 and int(date.tm_min) == 0 and int(date.tm_sec) >= 58:#整点清零
            preciseOutNum = 0
            preciseInNum = 0

        crossedAbove = 0  # 向上计数
        crossedBelow = 0  # 向下计数
        tmpQueue = set()

        peds,frame = arg1.get(True)
        frameBat = frame.copy()

        #移动检测

        if firstFrameFlag == False:
            gray1 = cv2.cvtColor(frameBat,cv2.COLOR_BGR2GRAY)
            gray2 = cv2.cvtColor(tempFrame,cv2.COLOR_BGR2GRAY)
            frameDelta = cv2.absdiff(gray1,gray2)
            rect,thresh = cv2.threshold(frameDelta,50,255,cv2.THRESH_BINARY)
            image,contour,hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
            tempFrame = frameBat.copy()
            for c in contour:
                #print "############",cv2.contourArea(c)
                if cv2.contourArea(c) > 100:
                    recordFlag = True
                    break
        else:
            tempFrame = frameBat.copy()
            firstFrameFlag = False


        #计数
        pedsPos = set()#行人位置信息集合
        for (x,y,w,h) in peds:
            tmp = (x,y,w,h)
            pedsPos.add(tmp)
            #recordFlag = True

        #过滤重叠的标记
        pedsTmp = pedsPos.copy()
        for ped in pedsTmp:
           (x1,y1,w1,h1) = ped
           for tmp in pedsTmp:
               (x2,y2,w2,h2) = tmp
               dist = cv2.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
               len = int(dist[0])
               r1 = w1/2
               r2 = w2/2
               if (len < r1+r2) and (len  > abs(r1-r2)):
                   print pedsPos,"remove",tmp
                   pedsPos.remove(ped)
                   break


        for (x, y, w, h) in pedsPos:
            if w < 80:
                print w, h
                if parameter.debugMode == True:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
                    cv2.circle(frame, (int(x + (w / 2)), int(y + (h / 2))), int(w / 2), (0, 1, 255), 2)
                tmpinfo = (int(x + w / 2), int(y + h / 2), x, y, w, h)
                tmpQueue.add(tmpinfo)

        #清除更新标志
        for tmpped in pedQueue:
            tmpped.updateInfoFlagClear()

        # 处理两帧之间的跟踪物体信息
        tmpQueues = tmpQueue.copy()
        for tmpQ in tmpQueues:
            minDistance = parameter.moveMinLen    #每一帧最小移动的距离
            updatePed = None
            for tmpped in pedQueue:#行人列队
                if tmpped.getUpdateFlagStatus() == True:#这个行人已经有跟踪对象了
                    continue
                dist  = tmpped.getDistInfo(tmpQ)
                if dist < minDistance:
                    minDistance = dist
                    updatePed = tmpped
            if None != updatePed:
                updatePed.updateInfoTrack(minDistance,tmpQ)
                tmpQueue.remove(tmpQ)
        #标记跟踪丢失的人
        for tmpped in pedQueue:
            tmpped.updateInfoTrackLost()

        #for tmpped in pedQueue:#当前帧的行人列队
        #    tmpped.updateInfo(tmpQueue)

        # 处理状态丢失的人体
        for tmpped in pedQueue:
            tmpped.lostPoress(tmpQueue)

        # 新增的人
        for info in tmpQueue:
            #print "add pedestrian"
            #showWinImage("frambat"+str(id), frameBat)
            (posx,posy,x,y,w,h) = info
            if checkLinea1(posx, posy) < 0 or checkLinea2(posx, posy) > 0:  # 两条线之间的人都不是新增的
                tmpped = pedestrian(info, id)
                id += 1
                pedQueue.add(tmpped)
            #else:

            #print 'add pedestrian fail'

        pedQueues = pedQueue.copy()
        for tmpped in pedQueues:
            if tmpped.checkPedExit():#没有跟踪这个行人
                if tmpped.cntFlagGet() == False:
                    (sx, sy, spx, spy, sw, sh) = tmpped.startPosGet()
                    (nx, ny, npx, npy, nw, nh) = tmpped.getPedNewInfo()
                    if checkLinea2(sx, sy) > 0 and checkLinea1(nx,ny) < 0:#起始位置判断 走进
                        print 'Ped In Tracking lost', sx, sy, nx, ny,tmpped.id
                        crossedAbove += 1
                    elif checkLinea1(sx, sy) < 0 and checkLinea2(nx,ny) > 0:#走出
                        print 'Ped Out Tracking lost', sx, sy, nx, ny,tmpped.id
                        crossedBelow += 1
                    elif checkLinea1(nx,ny) > 0 and checkLinea2(nx,ny) < 0:#跟踪丢失的时候这个在两条线中间根据起始位置判断
                        print 'Ped Tracking lost is middle',sx,sy,nx,ny,tmpped.id
                        if checkLinea1(sx,sy) < 0:#如果中间消失的人一开始在第一根计数线之上
                            crossedBelow += 1 #出
                        elif checkLinea2(sx,sy) > 0:#如果中间消失的人一开始在第二根计数线之下
                            crossedAbove += 1 #进
                    #以上这个补漏计的情况容易在某些情况下造成多计。
                pedQueue.remove(tmpped)
                #print  "Exit remove ped"
            else:
                tmpped.show(frame)#显示正在跟踪的人包括跟踪丢失的
                # print pedQueue
        # 列队
        for i in pedQueue:
            if i.cntFlagGet(): #如果这个人已经记过了但是没有离开就不计数了
                pass
                #print 'This ped is count num'
                #continue
            (nx, ny, npx, npy, nw, nh) = i.getPedNewInfo()
            (ox, oy, opx, opy, ow, oh) = i.getPedOldInfo()
            nx = int(nx)
            ny = int(ny)

            ox = int(ox)
            oy = int(oy)
            NewPedInfo = (int(nx), int(ny))
            OldPedInfo = (int(ox), int(oy))
            # print i.id, NewPedInfo ,OldPedInfo
            #if checkLinea1(nx, ny) > 0 and checkLinea2(nx, ny) < 0:  # 两条线之间的人
                #pointInMiddle.add(NewPedInfo)
            if checkLinea1(nx, ny) >= 0 and checkLinea2(nx, ny) <= 0:  # 两条线之间
                if checkLinea1(ox, oy) < 0:#上一次在第一条线的上面
                    pointFromAbove.add(NewPedInfo)
                elif checkLinea2(ox, oy) > 0:#上一次是在第二条线的下面
                    pointFromBelow.add(NewPedInfo)
                else:#上一次就在中间
                    if OldPedInfo in pointFromBelow:
                        pointFromBelow.remove(OldPedInfo)
                        pointFromBelow.add(NewPedInfo)
                    elif OldPedInfo in pointFromAbove:
                        pointFromAbove.remove(OldPedInfo)
                        pointFromAbove.add(NewPedInfo)

            if checkLinea1(nx, ny) < 0 and (OldPedInfo in pointFromBelow):#走进
                if (ow / pedWidth) > 4 and oh >= pedHigth:
                    crossedAbove += 2
                    i.cntFlagSet()#跟踪标记
                else:
                    if i.cntFlagGet():#已经被跟踪的人
                        #i.cntFlagSet(arg = False)
                        #crossedBelow -= 1
                        crossedAbove += 1
                    else:
                        crossedAbove += 1
                        i.cntFlagSet()#跟踪标记
                pointFromBelow.remove(OldPedInfo)
                print crossedAbove

            if checkLinea2(nx, ny) > 0 and (OldPedInfo in pointFromAbove):#走出
                if ow / pedWidth > 4 and oh >= pedHigth:
                    crossedBelow += 2
                    i.cntFlagSet()#跟踪完成标记
                else:
                    if i.cntFlagGet():
                        #i.cntFlagSet(arg = False)#这个人进出各一次但是没有离开监控区域
                        #crossedAbove -= 1
                        crossedBelow += 1
                    else:
                        crossedBelow += 1
                        i.cntFlagSet()#跟踪完成标记
                pointFromAbove.remove(OldPedInfo)
                print crossedBelow

        #linea1 = proportional(int(dev.area_x1*parameter.videoWidth), int(dev.area_y1*parameter.videoHigh), int(dev.area_x2*parameter.videoWidth), int(dev.area_y1*parameter.videoHigh+1))
        #linea2 = proportional(int(dev.area_x1*parameter.videoWidth), int(dev.area_y2*parameter.videoHigh), int(dev.area_x2*parameter.videoWidth), int(dev.area_y2*parameter.videoHigh+1))

        cv2.line(frame, (linea1.x1, linea1.y1), (linea1.x2, linea1.y2), (255, 0, 0), 1)
        cv2.line(frame, (linea2.x1, linea2.y1), (linea2.x2, linea2.y2), (255, 0, 0), 1)

        speedtmp += int(1/(time.time() - p_start))
        speedcnt += 1
        frameSped = int(speedtmp / speedcnt)
        if speedcnt >= 100:
            speedtmp = 0
            speedcnt = 0

        cv2.putText(frame, 'in =' + str(preciseInNum), (0, 15), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                    (0, 255, 100), 1, cv2.LINE_AA)
        cv2.putText(frame, 'out=' + str(preciseOutNum), (0, 33), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                    (0, 255, 100), 1, cv2.LINE_AA)
        if parameter.debugMode == True:
            cv2.putText(frame, 'fps=' + str(frameSped), (0, 50), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                        (0, 255, 255), 1, cv2.LINE_AA)
            cv2.putText(frame, 'IP:' + str(ip), (60, 235), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                        (0, 255, 255), 1, cv2.LINE_AA)
        else:
            cv2.putText(frame, 'IP:' + str(ip), (60, 235), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1,
                        (0, 255, 255), 1, cv2.LINE_AA)
        #cx = int(parameter.videoWidth / 2 - parameter.videoWidth / 2)
        #cy = int(parameter.videoHigh / 2 - parameter.videoHigh / 2)
        #cv2.rectangle(frame, (cx, cy), (cx + pedWidth, cy + pedHigth), (0, 200, 0), 1, lineType=cv2.LINE_AA)

        showWinImage("frame", frame)

        #如果不是Windows系统则录像
        if WindowsSystem == False:
            arg3.put([frame,frameBat,recordFlag])#处理帧，原始帧、录像标志

        if crossedAbove != 0 or crossedBelow != 0 or speedcnt == 0:
            pedNum = (int(crossedAbove),int(crossedBelow),frameSped)
            #print 'result:',arg2.qsize()
            preciseInNum += pedNum[0]
            preciseOutNum += pedNum[1]
            #pedNum = (int(preciseInNum),int(preciseOutNum),frameSped)
            arg2.put(pedNum)
        cv2.waitKey(1)
        #print "CPU3:", (time.time() - p_start)

def processCpu4(arg1,arg2,arg3):
    '''
    @ CPU4核处理任务，由于CPU4处理任务比较杂单独用一个模块来写
    :param arg1: 客流数据输入邮箱
    :param arg2: 录像数据输入邮箱
    :return:
    '''
    dataDeal.init(arg1,arg2,arg3)

def net_config_file_process():
    if os.path.isfile('/etc/network/interfaces') == False:#没有网络配置文件
        os.system('cp /home/fa/work/SmartCount/interfaces_wifi /etc/network/interfaces')#直接配置启动热点
    else:#有网络配置文件
        result = commands.getstatusoutput("cat /etc/network/interfaces | grep static -o")#检测当前WIFI是否为热点配置状态
        output = result[1]
        print output
        if output == 'static':#开机就是二点配置那么，先尝试一起的WIFI配置
            os.system("systemctl daemon-reload")
            os.system('/etc/init.d/hostapd stop')#停止hdcp服务器
            os.system('/etc/init.d/dnsmasq stop')#停止dns服务器
            os.system("killall hostapd")
            os.system("killall dnsmasq")
            os.system("cp /home/fa/work/SmartCount/interfaces /etc/network/interfaces")
            os.system('/etc/init.d/networking restart')
            os.system("killall udhcpc;udhcpc -i wlan1 -n")

if __name__ == '__main__':
    '''
    @主函数入口，主要任务创建队列（邮箱）和进程。
    '''
    net_config_file_process()
    pool = mp.Pool(processes=mp.cpu_count())
    manager = mp.Manager()
    FrameQueue = manager.Queue(100)
    FgmaskQueue = manager.Queue(100)
    PedNumQueue = manager.Queue(200)
    FrameRQueue = manager.Queue(100)


    # CPU1 CPU2 CPU3 CPU4三个进程
    r1 = pool.apply_async(func = processCpu1,args = (FrameQueue,))
    r2 = pool.apply_async(func = processCpu2,args = (FrameQueue,FgmaskQueue,devconfig))
    r3 = pool.apply_async(func = processCpu3,args=(FgmaskQueue,PedNumQueue,FrameRQueue,devconfig))
    r4 = pool.apply_async(func = processCpu4,args=(PedNumQueue,FrameRQueue,devconfig))
    if parameter.UseingFlaskVideo == True:
        print 'flask video start'
        os.system("python flaskVideo.py &")
    print "main end"
    pool.close()
    pool.join()
